package com.graduation.vaccine.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.graduation.vaccine.exception.GlobalException;
import com.graduation.vaccine.mapper.AppointmentMapper;
import com.graduation.vaccine.mapper.DepartmentProductionMapper;
import com.graduation.vaccine.mapper.ProductionMapper;
import com.graduation.vaccine.pojo.Appointment;
import com.graduation.vaccine.pojo.DepartmentProduction;
import com.graduation.vaccine.service.IAppointmentService;
import com.graduation.vaccine.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author ZhaoJunYao
 * @since 2022-04-22
 */
@Service
public class AppointmentServiceImpl extends ServiceImpl<AppointmentMapper, Appointment> implements IAppointmentService {

    @Autowired
    private AppointmentMapper appointmentMapper;
    @Autowired
    private ProductionMapper productionMapper;
    @Autowired
    private DepartmentProductionMapper departmentProductionMapper;

    @Override
    public RespBean getListByPhone(String phone) {
        return RespBean.success(appointmentMapper.getListByPhone(phone));
    }

    /**
     * 提交预约订单
     * @param appointmentVo
     * @return
     */
    @Override
    public RespBean addOne(AppointmentVo appointmentVo) throws ParseException {

        //有余量才可预约
        String departmentCode=appointmentVo.getDepartmentcode();
        Integer productionId=appointmentVo.getProductionId();
        DepartmentProduction departmentProduction=departmentProductionMapper.getTotalByDepartmentCodeAndProductionId(departmentCode,productionId);
        DataListVo dataListVo=new DataListVo();
        dataListVo.setDepartmentcode(departmentCode);
        dataListVo.setProductionId(productionId);
        //获取七天来每天该部门下疫苗的预约总数
        List<DataListInfo> dataListInfos=appointmentMapper.getDataList(dataListVo);
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        Date appointmentTime=sdf.parse(appointmentVo.getAppointmentTime());
        List<Date> unAcceptableDays=getUnAcceptableDays(dataListInfos);
        if(unAcceptableDays.contains(appointmentTime)){
            return RespBean.error(RespBeanEnum.NO_STOCK,1);
        }
        if(departmentProduction.getTotal()<=0){
            return RespBean.error(RespBeanEnum.NO_STOCK,1);
        }

        //未预约过才能预约(根据idCardNumber在appointment表中找是否有在预约状态的productId)
        List<Appointment> appointments=appointmentMapper.getListByIdCardNumberAndProductId(appointmentVo.getIdCardNumber(),appointmentVo.getProductionId());
        //预约过
        if(appointments!=null && !appointments.isEmpty()){
            return RespBean.error(RespBeanEnum.UNREPETABLE_APPLY,2);
        }
        //当天只可预约一个疫苗(根据日期和IDCard查)
        List<Appointment> appointmentList=appointmentMapper.getListByIdCardNumberAndDate(appointmentVo.getIdCardNumber(),appointmentVo.getAppointmentTime());
        if(appointmentList!=null && !appointmentList.isEmpty()){
            return RespBean.error(RespBeanEnum.FORBIDDEN_APPLY,3);
        }
        //添加订单表
        if(appointmentMapper.addOne(appointmentVo)<=0){
            return RespBean.error(RespBeanEnum.UPDATE_ERROR,"提交失败");
        }
        //提交成功则减库存(乐观锁)
        if(departmentProductionMapper.reduceTotal(appointmentVo.getDepartmentcode(),appointmentVo.getProductionId(),departmentProduction.getVersion())<=0){
            return RespBean.error(RespBeanEnum.UPDATE_ERROR,"更新失败");
        }

        return RespBean.success("预约成功！");
    }

    /**
     * 获取可预约时间
     * @param dataListVo
     * @return
     */
    @Override
    public RespBean getDataList(DataListVo dataListVo) throws ParseException {

        //获取七天来所有状态码为已完成的订单
        List<DataListInfo> dataList=appointmentMapper.getDataList(dataListVo);
        //获取产品余量
        Integer stock=0;
        try{
            DepartmentProduction departmentProduction=departmentProductionMapper.getTotalByDepartmentCodeAndProductionId(dataListVo.getDepartmentcode(),dataListVo.getProductionId());
            if(departmentProduction!=null){
                stock=departmentProduction.getTotal();
            }else {
                return  RespBean.success(RespBeanEnum.NO_DATA,"该部门下无产品数据");
            }
        }catch (Exception e){
            e.printStackTrace();
            throw new GlobalException(RespBeanEnum.ILLEGAL_DEPARTMENTCODE);
        }

        if(stock<0){
            return RespBean.error(RespBeanEnum.NO_STOCK,null);
        }
        //从今天开始的七天
        List<LocalDate> dates=new ArrayList<>();
        LocalDate today=LocalDate.now();
        dates.add(today);
        for(int i=1;i<7;i++){
            dates.add(today.plus(i, ChronoUnit.DAYS));
        }
        //不可预约的时间
        List<Date> unAcceptableDays=getUnAcceptableDays(dataList);
        List<String> acceptableDays=new ArrayList<>();

//        LocalDate localDate = LocalDate.now();
//        System.out.println("LocalDate = " + localDate);
//        Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
//        System.out.println("Date      = " + date);

        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        //遍历近七天
        for(LocalDate localDate:dates){
            Date date1=Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
            if(!unAcceptableDays.equals(date1)){
                acceptableDays.add(sdf.format(date1));
            }
        }
        return RespBean.success(acceptableDays);
    }

    @Override
    public RespBean getListByCode(String departmentCode) {
        return RespBean.success(appointmentMapper.getListByCode(departmentCode));
    }

    @Override
    public RespBean updateStatus(Integer id, Integer status,Integer current) {
        //修改状态(0: 已预约  1：待留观  2：接种完成  -1:取消订单 )
        //0<——>-1，0->1,1->2(单向)
        int currentStatus=appointmentMapper.getStatusById(id);
        System.out.println("当前状态是："+currentStatus);
        switch (currentStatus){
            case -1:
                return RespBean.error(RespBeanEnum.UPDATE_STATUS_ERROR,"订单已取消或过时，不可再更改");
            case 0:
                if(status==3){
                    if(appointmentMapper.updateStatus(id,status,null)<1){
                        return RespBean.error(RespBeanEnum.UPDATE_ERROR,"更新状态失败!");
                    }
                    return RespBean.success();
                }else if(status==1){
                    Date date=new Date(System.currentTimeMillis());
                    if(appointmentMapper.updateStatus(id,status,date)<1){
                        return RespBean.error(RespBeanEnum.UPDATE_ERROR,"更新状态失败!");
                    }
                    return RespBean.success();
                }else{
                    return RespBean.error(RespBeanEnum.UPDATE_STATUS_ERROR,"已预约订单只能取消订单或者带留观");
                }
            case 1:
                if(status==2){
                    if(appointmentMapper.updateStatus(id,status,null)<1){
                        return RespBean.error(RespBeanEnum.UPDATE_ERROR,"更新状态失败!");
                    }
                    return RespBean.success();
                }else{
                    return RespBean.error(RespBeanEnum.UPDATE_STATUS_ERROR,"已接种疫苗只能修改至接种完成！");
                }
            default:
                return RespBean.error(RespBeanEnum.UPDATE_STATUS_ERROR,"已完成订单不可修改！");
        }

    }

    //不可预约时间
    public List<Date> getUnAcceptableDays(List<DataListInfo> dataListInfos){
        List<Date> list=new ArrayList<>();
        for(DataListInfo dataListInfo:dataListInfos){
            //每日预约量大于50的为不可预约
            if(dataListInfo.getTotal()<=0||dataListInfo.getTotal()>=50){
                list.add(dataListInfo.getTime());
            }
        }
        return list;
    }
}
